home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / windownt / wvnsrc75.zip / WINVN.C < prev    next >
C/C++ Source or Header  |  1993-02-03  |  18KB  |  593 lines

  1. /*  WinVn.c
  2.  *
  3.  *  This program is a visual Usenet news reader for Microsoft Windows.
  4.  *  It bears a vague similarity to the Unix program "vn"; hence the
  5.  *  name WINVN.
  6.  *
  7.  *  WinVN talks NNTP (Network News Transport (?) Protocol) to a news
  8.  *  server, which must be running the NNTP program.  (The source for
  9.  *  a unix implementation of NNTP is readily and apparently freely
  10.  *  available.)
  11.  *
  12.  *  WINVN currently only reads articles; it does not allow posting
  13.  *  or mailing.  Posting will be implemented when I get around to it;
  14.  *  the delay is due to the need to first implement an authentication
  15.  *  scheme so we know the poster is accurately identified.
  16.  *
  17.  *  For more information, see WINVN.WRI and WVDOC.C.
  18.  *
  19.  *  Mark Riordan    September - October 1989    riordanmr@clvax1.cl.msu.edu
  20.  *  1100 Parker  Lansing, MI  48912
  21.  */
  22.  
  23.  
  24. #define WINMAIN
  25. #include "windows.h"
  26. #include "WVglob.h"
  27. #include "WinVn.h"
  28. #ifndef MAC
  29. #include "winundoc.h"
  30. #endif
  31. #include "ctype.h"
  32.  
  33. #include <stdlib.h>
  34.  
  35. char *CommStrtoID (char *, int *, int *, char *);
  36.  
  37. /*--- function WinMain -----------------------------------------------
  38.  *
  39.  *  Main program for WinVN.
  40.  *  Initialize, then execute main loop.
  41.  *
  42.  *    Entry    hInstance      is a handle to this instance of execution
  43.  *                            of this program.
  44.  *             hPrevInstance  is a handle to a previous instance
  45.  *                            of execution of this program (usually
  46.  *                            0, i.e., none.  Few people would have
  47.  *                            two copies of WinVN running simultaneously.)
  48.  *             lpCmdLine      points to the command line--currently
  49.  *                            not used.  (Not to useful for Windows programs.)
  50.  *             nCmdShow       is a flag indicating that the main window
  51.  *                            should be displayed.  (Fairly worthless.)
  52.  */
  53.  
  54. int PASCAL 
  55. WinMain (hInstance, hPrevInstance, lpCmdLine, nCmdShow)
  56.      HANDLE hInstance;
  57.      HANDLE hPrevInstance;
  58.      LPSTR lpCmdLine;
  59.      int nCmdShow;
  60. {
  61.   HWND hWnd;
  62.   HDC hDC;
  63.  
  64.   if (!hPrevInstance)
  65.     if (!WinVnInit (hInstance))
  66.       return (0);
  67. #ifndef MAC
  68.   hInst = hInstance;
  69. #endif
  70.  
  71.   /* Set up communications--serial or IP.                           */
  72.  
  73.   MRRInitComm ();
  74.  
  75.   /* Initialize the document that will contain the list of          */
  76.   /* newsgroups.  This will be the main window.                     */
  77.  
  78.   InitDoc (&NetDoc, (HWND) 0, (TypDoc *) NULL, DOCTYPE_NET);
  79.  
  80.   /* Create and display the main window.  At first, the window      */
  81.   /* just has an initialization message in it.                      */
  82.  
  83.   hWnd = CreateWindow ("WinVn",
  84.                "WinVN -- Usenet News Reader",
  85.                WS_OVERLAPPEDWINDOW | WS_VSCROLL,
  86.                0,    /* Initial X position */
  87.                0,    /* Initial Y position */
  88.                (int) (xScreen * 1 / 2),    /* Initial X width */
  89.                (int) (yScreen * 9 / 10),/* Initial Y height */
  90.                NULL,
  91.                NULL,
  92.                hInstance,
  93.                NULL);
  94.  
  95.   if (!hWnd)
  96.     return (0);
  97.  
  98.   hWndConf = hWnd;
  99.   NetDoc.hDocWnd = hWnd;    /* mrr */
  100.  
  101.   MoreInit ();
  102.  
  103. #ifndef MAC
  104.   ShowWindow (hWnd, nCmdShow);
  105. #endif
  106.   UpdateWindow (hWnd);
  107.   SendMessage (hWnd, WM_SIZE, 0, 0L);
  108.  
  109.   /* Read the NEWSRC file and display its contents in the           */
  110.   /* main window.                                                   */
  111.  
  112.   if (!ReadNewsrc ())
  113.     {
  114.       MessageBox (hWndConf, "Cannot open the NEWSRC file.", "Fatal error", MB_OK | MB_ICONHAND);
  115.       PostQuitMessage (0);
  116.     }
  117.   Initializing = INIT_ESTAB_CONN;
  118.   InvalidateRect (hWnd, NULL, FALSE);
  119.  
  120.   /* And now for the main loop, which appears in all Windows programs. */
  121.  
  122. #ifndef MAC
  123.   hAccel = LoadAccelerators (hInstance, "WinVNAccel");
  124. #endif
  125. #ifndef MAC
  126.   while (MainLoopPass ());
  127.   return (MainMsg.wParam);
  128. #endif
  129. }
  130.  
  131. /* --- FUNCTION WinVnInit ---------------------------------------------
  132.  *
  133.  *    Initialize the program (first stage).
  134.  *    This routine does some initialization needed before the
  135.  *    creation of the main window.
  136.  *    I put off additional initialization until after the main
  137.  *    window is created.
  138.  *
  139.  *    Entry    hInstance   is a handle to the current instance of
  140.  *                         execution.
  141.  *
  142.  *    Exit     Window classes have been registered, and a small
  143.  *             amount of other window- and comm-related initialization
  144.  *             is done.
  145.  */
  146.  
  147. BOOL 
  148. WinVnInit (hInstance)
  149.      HANDLE hInstance;
  150. {
  151.   HANDLE hMemory;
  152.   PWNDCLASS pWndClass;
  153.   char mesbuf[60], mesbuf2[60];
  154.   char buf[60];
  155.   char *errptr;
  156.   char *env_var;
  157.   BOOL bSuccess;
  158.  
  159.   Initializing = INIT_READING_NEWSRC;
  160.   SaveNewsrc = TRUE;
  161.   CommLineLWAp1 = CommLineIn + MAXCOMMLINE;
  162.   LineHeight = 30;        /* kludge so Net window doesn't get divide-by-zero */
  163.  
  164. #ifndef MAC
  165.   szAppName = "WinVN";
  166.  
  167.   env_var = getenv ("WINVN");        /* get path to winvn.ini */
  168.  
  169.   if (lstrlen (env_var))
  170.    {
  171.      lstrcpy (szAppProFile, env_var);
  172.      if (*(szAppProFile + lstrlen (szAppProFile) - 1) == '\\')
  173.        lstrcat (szAppProFile, "winvn.ini");
  174.      else
  175.        lstrcat (szAppProFile, "\\winvn.ini");
  176.    }
  177.   else
  178.    {
  179.      MessageBox (hWndConf,"Environment variable WINVN not set.\nWINVN must point to your login directory\nto find your WINVN.INI and NEWSRC\nThis is done automatically if you are logged in\nor you can type \"SET WINVN=N:\\WINVN\"","Fatal Error", MB_OK | MB_ICONEXCLAMATION);
  180.      return (0);
  181.    }
  182.  
  183.   /* Read profile strings.   */
  184.  
  185.   AskComm = GetPrivateProfileInt (szAppName, "AskComm", ASK_COMM_INITIAL, szAppProFile);
  186.   UsingSocket = GetPrivateProfileInt (szAppName, "UseSocket", 1, szAppProFile);
  187.   GetPrivateProfileString (szAppName, "NNTPHost", "titan", NNTPHost, MAXNNTPSIZE,szAppProFile);
  188.   NNTPPort = GetPrivateProfileInt (szAppName, "NNTPPort", 119 ,szAppProFile);
  189.   GetPrivateProfileString (szAppName, "CommString", "COM1:9600,e,7", szCommString, MAXCOMMCHARS,szAppProFile);
  190.   errptr = CommStrtoID (szCommString, &CommPortID, &CommParityID, pszCommSpeed);
  191.   if (errptr)
  192.     {
  193.       strcpy (mesbuf, "Error parsing ");
  194.       strcat (mesbuf, szCommString);
  195.       MessageBox (hWndConf, errptr, mesbuf, MB_OK | MB_ICONEXCLAMATION);
  196.     }
  197.  
  198.   DoList = GetPrivateProfileInt (szAppName, "DoList", ID_DOLIST_ASK,szAppProFile);
  199.  
  200.   GetPrivateProfileString (szAppName, "UserName", "", UserName, MAILLEN,szAppProFile);
  201.   GetPrivateProfileString (szAppName, "MailAddress", "", MailAddress, MAILLEN,szAppProFile);
  202.   GetPrivateProfileString (szAppName, "Organization", "", Organization, MAILLEN,szAppProFile);
  203.  
  204.   FontSize = GetPrivateProfileInt (szAppName, "FontSize", 0, szAppProFile);
  205.   ArticleFontSize = GetPrivateProfileInt (szAppName, "ArticleFontSize", 0,szAppProFile);
  206.   GetPrivateProfileString (szAppName, "FontFace", "Helv", FontFace, 32,szAppProFile);
  207.   GetPrivateProfileString (szAppName, "ArticleFontFace", "Helv", ArticleFontFace, 32, szAppProFile);
  208.   FontBold = GetPrivateProfileInt (szAppName, "FontBold", TRUE, szAppProFile);
  209.   ArticleFixedFont = GetPrivateProfileInt (szAppName, "ArticleFixedFont", FALSE, szAppProFile);
  210.   GetPrivateProfileString (szAppName, "NetUnSubscribedColor", "255,33,33" /*"200,60,150"*/ , buf, 32, szAppProFile);
  211.   NetUnSubscribedColor = StrToRGB (buf);
  212.   GetPrivateProfileString (szAppName, "GroupSeenColor", "80,100,235" /*"100,120,180"*/ , buf, 32, szAppProFile);
  213.   GroupSeenColor = StrToRGB (buf);
  214.   ViewNew = GetPrivateProfileInt (szAppName, "NewWndGroup", FALSE, szAppProFile);
  215.   NewArticleWindow = GetPrivateProfileInt (szAppName, "NewWndArticle", FALSE, szAppProFile);
  216.   SaveArtAppend = GetPrivateProfileInt (szAppName, "SaveArtAppend", TRUE, szAppProFile);
  217.   ThumbTrack = GetPrivateProfileInt (szAppName, "ThumbTrack", TRUE, szAppProFile);
  218.  
  219.   /* Create pointers to the dialog box functions, needed   */
  220.   /* for routine processing of dialog boxes.               */
  221.  
  222.   lpfnWinVnCommDlg = MakeProcInstance (WinVnCommDlg, hInstance);
  223.   lpfnWinVnSaveArtDlg = MakeProcInstance (WinVnSaveArtDlg, hInstance);
  224.   lpfnWinVnFindDlg = MakeProcInstance (WinVnFindDlg, hInstance);
  225.   lpfnWinVnSubjectDlg = MakeProcInstance (WinVnSubjectDlg, hInstance);
  226.   lpfnWinVnAuthDlg = MakeProcInstance (WinVnAuthDlg, hInstance);
  227.   lpfnWinVnDoListDlg = MakeProcInstance (WinVnDoListDlg, hInstance);
  228.   lpfnWinVnPersonalInfoDlg = MakeProcInstance (WinVnPersonalInfoDlg, hInstance);
  229.   lpfnWinVnMiscDlg = MakeProcInstance (WinVnMiscDlg, hInstance);
  230.   lpfnWinVnAppearanceDlg = MakeProcInstance (WinVnAppearanceDlg, hInstance);
  231.  
  232.   xScreen = GetSystemMetrics (SM_CXSCREEN);
  233.   yScreen = GetSystemMetrics (SM_CYSCREEN);
  234. #else
  235.   xScreen = screenBits.bounds.right;
  236.   yScreen = screenBits.bounds.bottom - 20;
  237.   TEHCurrent = 0;
  238. #endif
  239.   CommDoc = &NetDoc;
  240.   Authorized = FALSE;
  241.  
  242. #ifndef MAC
  243.   hMemory = LocalAlloc (LPTR, sizeof (WNDCLASS));
  244.   pWndClass = (PWNDCLASS) LocalLock (hMemory);
  245.   pWndClass->hCursor = LoadCursor (NULL, IDC_ARROW);
  246.   pWndClass->hIcon = LoadIcon (hInstance, (LPSTR) "winvn");
  247.   pWndClass->lpszMenuName = (LPSTR) "ConfMenu";
  248.   pWndClass->lpszClassName = (LPSTR) "WinVn";
  249.   pWndClass->hbrBackground = GetStockObject (WHITE_BRUSH);
  250.   pWndClass->hInstance = hInstance;
  251.   pWndClass->style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  252.   pWndClass->lpfnWndProc = WinVnConfWndProc;
  253.  
  254.   bSuccess = RegisterClass (pWndClass);
  255.  
  256.   if (bSuccess)
  257.     {
  258.       pWndClass->hCursor = LoadCursor (NULL, IDC_ARROW);
  259.       pWndClass->hIcon = LoadIcon (hInstance, (LPSTR) "wvgroup");
  260.       pWndClass->lpszMenuName = (LPSTR) "ViewMenu";
  261.       pWndClass->lpszClassName = (LPSTR) "WinVnView";
  262.       pWndClass->hbrBackground = GetStockObject (WHITE_BRUSH);
  263.       pWndClass->hInstance = hInstance;
  264.       pWndClass->style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  265.       pWndClass->lpfnWndProc = WinVnViewWndProc;
  266.  
  267.       bSuccess = RegisterClass (pWndClass);
  268.     }
  269.  
  270.   if (bSuccess)
  271.     {
  272.       pWndClass->hCursor = LoadCursor (NULL, IDC_ARROW);
  273.       pWndClass->hIcon = LoadIcon (hInstance, (LPSTR) "wvart");
  274.       pWndClass->lpszMenuName = (LPSTR) "ArtMenu";
  275.       pWndClass->lpszClassName = (LPSTR) "WinVnArt";
  276.       pWndClass->hbrBackground = GetStockObject (WHITE_BRUSH);
  277.       pWndClass->hInstance = hInstance;
  278.       pWndClass->style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  279.       pWndClass->lpfnWndProc = WinVnArtWndProc;
  280.  
  281.       bSuccess = RegisterClass (pWndClass);
  282.     }
  283.  
  284.   if (bSuccess)
  285.     {
  286.       pWndClass->hCursor = LoadCursor (NULL, IDC_ARROW);
  287.       pWndClass->hIcon = LoadIcon (hInstance, (LPSTR) "wvpost");
  288.       pWndClass->lpszMenuName = (LPSTR) "PostMenu";
  289.       pWndClass->lpszClassName = (LPSTR) "WinVnPost";
  290.       pWndClass->hbrBackground = GetStockObject (WHITE_BRUSH);
  291.       pWndClass->hInstance = hInstance;
  292.       pWndClass->style = CS_HREDRAW | CS_VREDRAW;
  293.       pWndClass->lpfnWndProc = WinVnPostWndProc;
  294.  
  295.       bSuccess = RegisterClass (pWndClass);
  296.     }
  297.  
  298.   if (bSuccess)
  299.     {
  300.       pWndClass->hCursor = LoadCursor (NULL, IDC_ARROW);
  301.       pWndClass->hIcon = LoadIcon (hInstance, (LPSTR) "wvmail");
  302.       pWndClass->lpszMenuName = (LPSTR) "MailMenu";
  303.       pWndClass->lpszClassName = (LPSTR) "WinVnMail";
  304.       pWndClass->hbrBackground = GetStockObject (WHITE_BRUSH);
  305.       pWndClass->hInstance = hInstance;
  306.       pWndClass->style = CS_HREDRAW | CS_VREDRAW;
  307.       pWndClass->lpfnWndProc = WinVnMailWndProc;
  308.  
  309.       bSuccess = RegisterClass (pWndClass);
  310.     }
  311.  
  312.   LocalUnlock (hMemory);
  313.   LocalFree (hMemory);
  314. #else
  315.   bSuccess = TRUE;
  316. #endif
  317.   return (bSuccess);
  318. }
  319.  
  320. /* --- Function MoreInit -----------------------------------------------
  321.  *
  322.  *    Finish up initializing the program.
  323.  *    I do as much initialization here as possible.  I'd rather
  324.  *    have code run after the main window is created (in WinVNInit),
  325.  *    so I have someplace to display error messages if necessary.
  326.  *
  327.  *    I read quite a few profile strings (from WIN.INI)
  328.  *    here and act appropriately (usually means setting a global variable).
  329.  *    I try to read as many as possible of the profile strings used by this
  330.  *    program here.
  331.  *    In particular, I do a bunch of font stuff here.
  332.  */
  333.  
  334. BOOL
  335. MoreInit ()
  336. {
  337.   char szComName[10];
  338.   int retcode, j;
  339. #ifndef MAC
  340.   TEXTMETRIC tmFontInfo;
  341.   char mesbuf[50];
  342.  
  343.   HDC hDC;
  344.  
  345.  
  346.   CheckView (hWndConf);        /* modify menu as necessary           */
  347.  
  348.   hDC = GetDC (hWndConf);
  349.   /* Unless user specified the system font, create a font as per
  350.    * the user's specifications.
  351.    */
  352. /*  sprintf (mesbuf, "FontFace = %s, Bold = %d", FontFace,FontBold);
  353.   MessageBox (hWndConf, mesbuf, "Hey!", MB_OK);
  354. */
  355.  
  356.   if (FontSize)
  357.     {
  358.         hFont = CreateFont (FontSize,
  359.         0,    /* width */
  360.         0,    /* escapement */
  361.         0,    /* orientation */
  362.         FontBold ? FW_BOLD : FW_MEDIUM,
  363.         0,    /* no italics */
  364.         0,    /* no underline */
  365.         0,    /* no strikeout */
  366.         0,
  367.         OUT_DEFAULT_PRECIS,
  368.         CLIP_DEFAULT_PRECIS,
  369.         0,    /* no PROOF_QUALITY */
  370.         0,
  371.         FontFace);
  372.     }
  373.     else
  374.     {
  375.         hFont = GetStockObject (OEM_FIXED_FONT);
  376.     }
  377.  
  378.     if (ArticleFontSize && !ArticleFixedFont)
  379.     {
  380.         hFontArt = CreateFont (ArticleFontSize,
  381.         0,    /* width */
  382.         0,    /* escapement */
  383.         0,    /* orientation */
  384.         FW_MEDIUM,    /* default weight */
  385.         0,    /* no italics */
  386.         0,    /* no underline */
  387.         0,    /* no strikeout */
  388.         0,
  389.         OUT_DEFAULT_PRECIS,
  390.         CLIP_DEFAULT_PRECIS,
  391.         0,    /* no PROOF_QUALITY */
  392.         0,
  393.         ArticleFontFace);
  394.     }
  395.     else if (ArticleFixedFont)
  396.     {
  397.         hFontArt = GetStockObject (ANSI_FIXED_FONT);
  398.     }
  399.     else
  400.     {
  401.         hFontArt = hFont;
  402.     }
  403.  
  404.   ReleaseDC (hWndConf, hDC);
  405.  
  406.   /*  Get information about the font.  LineHeight and CharWidth
  407.    *  are pretty self-explanatory and the methods of determining these
  408.    *  are standard.  TopSpace and SideSpace are the top and left margins
  409.    *  in pixels; I compute them by a method I determined empirically.
  410.    */
  411.  
  412.   hDC = GetDC (hWndConf);
  413.   SelectObject (hDC, hFont);
  414.   GetTextMetrics (hDC, (LPTEXTMETRIC) & tmFontInfo);
  415.  
  416.   LineHeight = tmFontInfo.tmExternalLeading + tmFontInfo.tmHeight;
  417.   CharWidth = tmFontInfo.tmAveCharWidth;
  418.   TopSpace = tmFontInfo.tmExternalLeading;
  419.   TopSpace = LineHeight / 4;
  420.   StartPen = TopSpace;
  421.   SideSpace = tmFontInfo.tmAveCharWidth / 2;
  422.   ReleaseDC (hWndConf, hDC);
  423.  
  424.   hDC = GetDC (hWndConf);
  425.   SelectObject (hDC, hFontArt);
  426.   GetTextMetrics (hDC, (LPTEXTMETRIC) & tmFontInfo);
  427.  
  428.   ArtLineHeight = tmFontInfo.tmExternalLeading + tmFontInfo.tmHeight;
  429.   ArtCharWidth = tmFontInfo.tmAveCharWidth;
  430.   ReleaseDC (hWndConf, hDC);
  431.  
  432.  
  433. #else
  434.   BigClipRgn = NewRgn ();
  435.   SetRectRgn (BigClipRgn, 0, 0, 2000, 2000);
  436.   SetWindowVars ();
  437. #endif
  438.  
  439.   strcpy (SaveArtFileName, "");
  440.  
  441.   /* Initialize some document-related stuff.                        */
  442.  
  443.   ActiveGroupDoc = (TypDoc *) NULL;
  444.   ActiveArticleDoc = (TypDoc *) NULL;
  445.   for (j = 0; j < MAXGROUPWNDS; j++)
  446.     GroupDocs[j].InUse = FALSE;
  447.   for (j = 0; j < MAXARTICLEWNDS; j++)
  448.     ArticleDocs[j].InUse = FALSE;
  449.  
  450.   return retcode;
  451. }
  452.  
  453. #ifndef MAC
  454.  
  455. /*--- Function WinVnDoComm  -----------------------------------
  456.  *
  457.  *  Set communications parameters.
  458.  *
  459.  *  Entry    szComm         is a string equivalent to that on a MODE statement.
  460.  *                          E.g.,  "COM1:2400,n,8"
  461.  */
  462. int
  463. WinVnDoComm (szComm)
  464.      char *szComm;
  465. {
  466.  
  467. #if 0
  468.   int retcode;
  469.   char mesbuf[60];
  470.  
  471.   if (retcode = BuildCommDCB (szComm, (DCB FAR *) & DCBComm))
  472.     {
  473.       sprintf (mesbuf, "BuildComm returned %d", retcode);
  474.       MessageBox (hWndConf, mesbuf, "Error building COM1 DCB", MB_OK | MB_ICONEXCLAMATION);
  475.     }
  476.   else
  477.     {
  478.       SetCommState ((DCB FAR *) & DCBComm);
  479.     }
  480.   return (retcode);
  481.  
  482. #endif
  483.  
  484. }
  485.  
  486. /*--- Function CommStrtoID --------------------------------------
  487.  *
  488.  *   Takes a communications string of the form given to the MODE command
  489.  *   and breaks it down to its constituent parts.
  490.  *
  491.  *   Entry    CommStr    is the string; e.g., "COM1:2400,n,8"
  492.  *
  493.  *   Exit     *Port      is the port (an IDD_* variable)
  494.  *            *Parity    is the parity/data bits infor (an IDD_* symbol)
  495.  *            szSpeed    is the speed, in character form
  496.  *            CommStr    has been converted to upper case.
  497.  *            Function value NULL if no error, else a pointer
  498.  *             to an error message.
  499.  */
  500. char *
  501. CommStrtoID (CommStr, Port, Parity, szSpeed)
  502.      char *CommStr;
  503.      int *Port, *Parity;
  504.      char *szSpeed;
  505. {
  506.   char *ptr, *Speedptr;
  507.   int myPort;
  508.  
  509.   strupr (CommStr);
  510.   ptr = CommStr;
  511.  
  512.   while (*(ptr) == ' ')
  513.     ptr++;
  514.  
  515.   /* Crack the "COMx" part of the string.                           */
  516.  
  517.   if (strncmp (ptr, "COM", 3) != 0)
  518.     return ("Must be COM port");
  519.   ptr += 3;
  520.  
  521.   if (*ptr == '1')
  522.     {
  523.       *Port = IDD_COM1;
  524.     }
  525.   else if (*ptr == '2')
  526.     {
  527.       *Port = IDD_COM2;
  528.     }
  529.   else
  530.     {
  531.       return ("COM port must be 1 or 2");
  532.     }
  533.  
  534.   /* Crack the speed parameter.                                     */
  535.  
  536.   ptr += 2;
  537.   while (*ptr == ' ')
  538.     ptr++;
  539.   for (Speedptr = szSpeed; isdigit (*ptr); *(Speedptr++) = *(ptr++));
  540.   *Speedptr = '\0';
  541.  
  542.   if (szSpeed == Speedptr)
  543.     {
  544.       return ("Non-numeric COM speed");
  545.     }
  546.  
  547.   while (isdigit (*ptr) || *ptr == ' ' || *ptr == ',')
  548.     ptr++;
  549.  
  550.   /* Crack the parity parameter.                                    */
  551.  
  552.   if (*ptr == 'N')
  553.     {
  554.       *Parity = IDD_8NONE;
  555.     }
  556.   else if (*ptr == 'E')
  557.     {
  558.       *Parity = IDD_7EVEN;
  559.     }
  560.   else
  561.     {
  562.       return ("Bad parity");
  563.     }
  564.  
  565.   return (NULL);
  566. }
  567.  
  568. /*--- function MainLoopPass ---------------------------------------------
  569.  *
  570.  *    Do one pass of the main loop.
  571.  *
  572.  *    Entry
  573.  *
  574.  *    Exit     returns result of GetMessage()
  575.  */
  576. BOOL
  577. MainLoopPass ()
  578. {
  579.   BOOL NoQuit;
  580.  
  581.   if (NoQuit = GetMessage (&MainMsg, NULL, NULL, NULL))
  582.     {
  583.       if (!TranslateAccelerator (MainMsg.hwnd, hAccel, &MainMsg))
  584.     {
  585.       TranslateMessage (&MainMsg);
  586.       DispatchMessage (&MainMsg);
  587.     }
  588.     }
  589.   return (NoQuit);
  590. }
  591.  
  592. #endif
  593.